package com.gxa.saas.portal.jms;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.gxa.saas.core.entity.TbAddress;
import com.gxa.saas.core.vo.EditOderVo;
import com.gxa.saas.core.vo.TbAddressVo;
import com.gxa.saas.portal.service.GBGoodsService;
import com.gxa.saas.portal.service.InsertIndentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.command.ActiveMQTextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Component
@Slf4j
public class GoodsCacheListener {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate=null;

    private static final String GOODSCACHE_USED="goodsCache_used";

    private static final String ODERID="oderIdCache:";

    private static final String NUM="1";

    private Connection conn = null;

    @Autowired
    private InsertIndentService insertIndentService;

    @Autowired
    private GBGoodsService gbGoodsService;

    /**
     * JmsListener配置了containerFactory属性,表示通过自定义的容器工厂加载JmsTemplate
     * 该容器工厂配置了事务和签收机制
     * 注入消息对象的时候,采用消息原本的状态: Message
     * ActiveMQ的消息id唯一，rabbitMQ的消息id每次都不同，
     * 所以rabbit得用uuid作为唯一判断
     * @param message 消息队列传输的Message对象
     * @param session
     * @throws JMSException
     */

    @JmsListener(destination="indentCachess",containerFactory = "containerFactory")
    public void subscribe(Message message, Session session)  throws JMSException{
        System.out.println("--------------------------------------------------------------------------------------------------");
        String text = ((ActiveMQTextMessage) message).getText();
        log.info("收到订阅的消息{}",text);
        try {
            //获取该消息的 id
            String jmsMessageID = message.getJMSMessageID();
            log.info("messageid是{}", jmsMessageID);

            //利用redis判断是否存在该消息
            HashOperations<String, Object, Object> opsForHash = redisTemplate.opsForHash();
            Object o = opsForHash.get(GOODSCACHE_USED, jmsMessageID);//1或null
            //如果返回消息不为空说明该消息曾经已经被记录过->是一条被成功消费过的消息
            if (!StringUtils.isEmpty(o)) {
                //应当立刻签收
                message.acknowledge();
                return;
            }
            BoundHashOperations<String,Object,Object> boundHashOps = redisTemplate.boundHashOps(text);
            Map tbAddressVo1 = (Map) boundHashOps.get("tbAddressVo");
            TbAddressVo tbAddressVo = JSON.parseObject(JSON.toJSONString(tbAddressVo1),new TypeReference<TbAddressVo>(){});
            Map editOderVo1 = (Map) boundHashOps.get("EditOderVo");
            EditOderVo editOderVo = JSON.parseObject(JSON.toJSONString(editOderVo1),new TypeReference<EditOderVo>(){});


            String oderId = text;

            try {
                editOderVo.setOederId(oderId);
                editOderVo.setOdTime(new Date());
                editOderVo.setStatus(0);
                editOderVo.setId(text);
                tbAddressVo.setAdAddress(tbAddressVo.getAdAddress()+tbAddressVo.getAdDetail());
                tbAddressVo.setOederId(oderId);
            }catch (Exception e){}
            this.insertIndentService.insertIndent(editOderVo);
            this.insertIndentService.insertIndents(tbAddressVo);
            String s = this.insertIndentService.selectPrIdAndId(editOderVo.getPrId());
            editOderVo.setPrId(s);
            try {
                insertIndentService.insertGoodsOder(editOderVo);
            }catch (Exception e){
                e.printStackTrace();
                log.error("插入订单信息失败");
            }
            ValueOperations<String, Object> stringOps = redisTemplate.opsForValue();
            stringOps.set(ODERID,oderId,20, TimeUnit.MINUTES);

            //为了防止重复消费将id做个记录
            opsForHash.put(GOODSCACHE_USED,jmsMessageID,1);
            message.acknowledge();

        }catch (Exception e){
            e.printStackTrace();
            log.error("添加订单失败");
        }


    }

    /*验证是否成功*/
    @JmsListener(destination="paymessageCatcheSS",containerFactory = "containerFactory")
    public void validationPay(Message message, Session session)  throws JMSException{
        System.out.println("----------------------------------------");
        System.out.println("消息监听消息监听消息监听");
        String text = ((ActiveMQTextMessage) message).getText();
        log.info("收到订阅的消息{}",text);
        try {
            //获取该消息的 id
            String jmsMessageID = message.getJMSMessageID();
            log.info("messageid是{}", jmsMessageID);

            //利用redis判断是否存在该消息
            HashOperations<String, Object, Object> opsForHash = redisTemplate.opsForHash();
            Object o = opsForHash.get(GOODSCACHE_USED, jmsMessageID);//1或null
            //如果返回消息不为空说明该消息曾经已经被记录过->是一条被成功消费过的消息
            if (!StringUtils.isEmpty(o)) {
                //应当立刻签收
                message.acknowledge();
                return;
            }
            String orderId = NUM+text;
            BoundHashOperations<String,Object,Object> boundHashOps = redisTemplate.boundHashOps(orderId);
            Map editOderVo1 = (Map) boundHashOps.get("EditOderVo");
            EditOderVo editOderVo = JSON.parseObject(JSON.toJSONString(editOderVo1),new TypeReference<EditOderVo>(){});
            insertIndentService.updateOrderStatus(orderId);
            insertIndentService.updateProductSales(editOderVo);

            //为了防止重复消费将id做个记录
            opsForHash.put(GOODSCACHE_USED,jmsMessageID,1);
            message.acknowledge();

        }catch (Exception e){
            e.printStackTrace();
        }


    }

    @JmsListener(destination = "HotCommodity")
    public void test01(Integer id){
        System.out.println("=============================="+id);
        Boolean aBoolean = gbGoodsService.HotCommodity(id);
        System.out.println("消息队列消费消息");
    }



}
